﻿package org.flixel
{
    import flash.display.*;
    import flash.geom.*;

    public class FlxCamera extends FlxBasic
    {
        public var x:Number;
        public var y:Number;
        public var width:uint;
        public var height:uint;
        public var target:FlxObject;
        public var deadzone:FlxRect;
        public var bounds:FlxRect;
        public var scroll:FlxPoint;
        public var buffer:BitmapData;
        public var bgColor:uint;
        public var screen:FlxSprite;
        protected var _zoom:Number;
        protected var _point:FlxPoint;
        protected var _color:uint;
        protected var _flashBitmap:Bitmap;
        var _flashSprite:Sprite;
        var _flashOffsetX:Number;
        var _flashOffsetY:Number;
        protected var _flashRect:Rectangle;
        protected var _flashPoint:Point;
        protected var _fxFlashColor:uint;
        protected var _fxFlashDuration:Number;
        protected var _fxFlashComplete:Function;
        protected var _fxFlashAlpha:Number;
        protected var _fxFadeColor:uint;
        protected var _fxFadeDuration:Number;
        protected var _fxFadeComplete:Function;
        protected var _fxFadeAlpha:Number;
        protected var _fxShakeIntensity:Number;
        protected var _fxShakeDuration:Number;
        protected var _fxShakeComplete:Function;
        protected var _fxShakeOffset:FlxPoint;
        protected var _fxShakeDirection:uint;
        protected var _fill:BitmapData;
        public static const STYLE_LOCKON:uint = 0;
        public static const STYLE_PLATFORMER:uint = 1;
        public static const STYLE_TOPDOWN:uint = 2;
        public static const STYLE_TOPDOWN_TIGHT:uint = 3;
        public static const SHAKE_BOTH_AXES:uint = 0;
        public static const SHAKE_HORIZONTAL_ONLY:uint = 1;
        public static const SHAKE_VERTICAL_ONLY:uint = 2;
        public static var defaultZoom:Number;

        public function FlxCamera(param1:int, param2:int, param3:int, param4:int, param5:Number = 0)
        {
            this.x = param1;
            this.y = param2;
            this.width = param3;
            this.height = param4;
            this.target = null;
            this.deadzone = null;
            this.scroll = new FlxPoint();
            this._point = new FlxPoint();
            this.bounds = null;
            this.screen = new FlxSprite();
            this.screen.makeGraphic(this.width, this.height, 0, true);
            this.screen.setOriginToCorner();
            this.buffer = this.screen.pixels;
            this.bgColor = FlxG.bgColor;
            this._color = 16777215;
            this._flashBitmap = new Bitmap(this.buffer);
            this._flashBitmap.x = (-this.width) * 0.5;
            this._flashBitmap.y = (-this.height) * 0.5;
            this._flashSprite = new Sprite();
            this.zoom = param5;
            this._flashOffsetX = this.width * 0.5 * this.zoom;
            this._flashOffsetY = this.height * 0.5 * this.zoom;
            this._flashSprite.x = this.x + this._flashOffsetX;
            this._flashSprite.y = this.y + this._flashOffsetY;
            this._flashSprite.addChild(this._flashBitmap);
            this._flashRect = new Rectangle(0, 0, this.width, this.height);
            this._flashPoint = new Point();
            this._fxFlashColor = 0;
            this._fxFlashDuration = 0;
            this._fxFlashComplete = null;
            this._fxFlashAlpha = 0;
            this._fxFadeColor = 0;
            this._fxFadeDuration = 0;
            this._fxFadeComplete = null;
            this._fxFadeAlpha = 0;
            this._fxShakeIntensity = 0;
            this._fxShakeDuration = 0;
            this._fxShakeComplete = null;
            this._fxShakeOffset = new FlxPoint();
            this._fxShakeDirection = 0;
            this._fill = new BitmapData(this.width, this.height, true, 0);
            return;
        }// end function

        override public function destroy() : void
        {
            this.screen.destroy();
            this.screen = null;
            this.target = null;
            this.scroll = null;
            this.deadzone = null;
            this.bounds = null;
            this.buffer = null;
            this._flashBitmap = null;
            this._flashRect = null;
            this._flashPoint = null;
            this._fxFlashComplete = null;
            this._fxFadeComplete = null;
            this._fxShakeComplete = null;
            this._fxShakeOffset = null;
            this._fill = null;
            return;
        }// end function

        override public function update() : void
        {
            var _loc_1:Number = NaN;
            var _loc_2:Number = NaN;
            var _loc_3:Number = NaN;
            if (this.target != null)
            {
                if (this.deadzone == null)
                {
                    this.focusOn(this.target.getMidpoint(this._point));
                }
                else
                {
                    _loc_2 = this.target.x + (this.target.x > 0 ? (1e-007) : (-1e-007));
                    _loc_3 = this.target.y + (this.target.y > 0 ? (1e-007) : (-1e-007));
                    _loc_1 = _loc_2 - this.deadzone.x;
                    if (this.scroll.x > _loc_1)
                    {
                        this.scroll.x = _loc_1;
                    }
                    _loc_1 = _loc_2 + this.target.width - this.deadzone.x - this.deadzone.width;
                    if (this.scroll.x < _loc_1)
                    {
                        this.scroll.x = _loc_1;
                    }
                    _loc_1 = _loc_3 - this.deadzone.y;
                    if (this.scroll.y > _loc_1)
                    {
                        this.scroll.y = _loc_1;
                    }
                    _loc_1 = _loc_3 + this.target.height - this.deadzone.y - this.deadzone.height;
                    if (this.scroll.y < _loc_1)
                    {
                        this.scroll.y = _loc_1;
                    }
                }
            }
            if (this.bounds != null)
            {
                if (this.scroll.x < this.bounds.left)
                {
                    this.scroll.x = this.bounds.left;
                }
                if (this.scroll.x > this.bounds.right - this.width)
                {
                    this.scroll.x = this.bounds.right - this.width;
                }
                if (this.scroll.y < this.bounds.top)
                {
                    this.scroll.y = this.bounds.top;
                }
                if (this.scroll.y > this.bounds.bottom - this.height)
                {
                    this.scroll.y = this.bounds.bottom - this.height;
                }
            }
            if (this._fxFlashAlpha > 0)
            {
                this._fxFlashAlpha = this._fxFlashAlpha - FlxG.elapsed / this._fxFlashDuration;
                if (this._fxFlashAlpha <= 0 && this._fxFlashComplete != null)
                {
                    this._fxFlashComplete();
                }
            }
            if (this._fxFadeAlpha > 0 && this._fxFadeAlpha < 1)
            {
                this._fxFadeAlpha = this._fxFadeAlpha + FlxG.elapsed / this._fxFadeDuration;
                if (this._fxFadeAlpha >= 1)
                {
                    this._fxFadeAlpha = 1;
                    if (this._fxFadeComplete != null)
                    {
                        this._fxFadeComplete();
                    }
                }
            }
            if (this._fxShakeDuration > 0)
            {
                this._fxShakeDuration = this._fxShakeDuration - FlxG.elapsed;
                if (this._fxShakeDuration <= 0)
                {
                    this._fxShakeOffset.make();
                    if (this._fxShakeComplete != null)
                    {
                        this._fxShakeComplete();
                    }
                }
                else
                {
                    if (this._fxShakeDirection == SHAKE_BOTH_AXES || this._fxShakeDirection == SHAKE_HORIZONTAL_ONLY)
                    {
                        this._fxShakeOffset.x = (FlxG.random() * this._fxShakeIntensity * this.width * 2 - this._fxShakeIntensity * this.width) * this._zoom;
                    }
                    if (this._fxShakeDirection == SHAKE_BOTH_AXES || this._fxShakeDirection == SHAKE_VERTICAL_ONLY)
                    {
                        this._fxShakeOffset.y = (FlxG.random() * this._fxShakeIntensity * this.height * 2 - this._fxShakeIntensity * this.height) * this._zoom;
                    }
                }
            }
            return;
        }// end function

        public function follow(param1:FlxObject, param2:uint = 0) : void
        {
            var _loc_3:Number = NaN;
            var _loc_4:Number = NaN;
            var _loc_5:Number = NaN;
            this.target = param1;
            switch(param2)
            {
                case STYLE_PLATFORMER:
                {
                    _loc_4 = this.width / 8;
                    _loc_5 = this.height / 3;
                    this.deadzone = new FlxRect((this.width - _loc_4) / 2, (this.height - _loc_5) / 2 - _loc_5 * 0.25, _loc_4, _loc_5);
                    break;
                }
                case STYLE_TOPDOWN:
                {
                    _loc_3 = FlxU.max(this.width, this.height) / 4;
                    this.deadzone = new FlxRect((this.width - _loc_3) / 2, (this.height - _loc_3) / 2, _loc_3, _loc_3);
                    break;
                }
                case STYLE_TOPDOWN_TIGHT:
                {
                    _loc_3 = FlxU.max(this.width, this.height) / 8;
                    this.deadzone = new FlxRect((this.width - _loc_3) / 2, (this.height - _loc_3) / 2, _loc_3, _loc_3);
                    break;
                }
                case STYLE_LOCKON:
                {
                }
                default:
                {
                    this.deadzone = null;
                    break;
                    break;
                }
            }
            return;
        }// end function

        public function focusOn(param1:FlxPoint) : void
        {
            param1.x = param1.x + (param1.x > 0 ? (1e-007) : (-1e-007));
            param1.y = param1.y + (param1.y > 0 ? (1e-007) : (-1e-007));
            this.scroll.make(param1.x - this.width * 0.5, param1.y - this.height * 0.5);
            return;
        }// end function

        public function setBounds(param1:Number = 0, param2:Number = 0, param3:Number = 0, param4:Number = 0, param5:Boolean = false) : void
        {
            if (this.bounds == null)
            {
                this.bounds = new FlxRect();
            }
            this.bounds.make(param1, param2, param3, param4);
            if (param5)
            {
                FlxG.worldBounds.copyFrom(this.bounds);
            }
            this.update();
            return;
        }// end function

        public function flash(param1:uint = 4.29497e+009, param2:Number = 1, param3:Function = null, param4:Boolean = false) : void
        {
            if (!param4 && this._fxFlashAlpha > 0)
            {
                return;
            }
            this._fxFlashColor = param1;
            if (param2 <= 0)
            {
                param2 = Number.MIN_VALUE;
            }
            this._fxFlashDuration = param2;
            this._fxFlashComplete = param3;
            this._fxFlashAlpha = 1;
            return;
        }// end function

        public function fade(param1:uint = 4.27819e+009, param2:Number = 1, param3:Function = null, param4:Boolean = false) : void
        {
            if (!param4 && this._fxFadeAlpha > 0)
            {
                return;
            }
            this._fxFadeColor = param1;
            if (param2 <= 0)
            {
                param2 = Number.MIN_VALUE;
            }
            this._fxFadeDuration = param2;
            this._fxFadeComplete = param3;
            this._fxFadeAlpha = Number.MIN_VALUE;
            return;
        }// end function

        public function shake(param1:Number = 0.05, param2:Number = 0.5, param3:Function = null, param4:Boolean = true, param5:uint = 0) : void
        {
            if (!param4 && (this._fxShakeOffset.x != 0 || this._fxShakeOffset.y != 0))
            {
                return;
            }
            this._fxShakeIntensity = param1;
            this._fxShakeDuration = param2;
            this._fxShakeComplete = param3;
            this._fxShakeDirection = param5;
            this._fxShakeOffset.make();
            return;
        }// end function

        public function stopFX() : void
        {
            this._fxFlashAlpha = 0;
            this._fxFadeAlpha = 0;
            this._fxShakeDuration = 0;
            this._flashSprite.x = this.x + this.width * 0.5;
            this._flashSprite.y = this.y + this.height * 0.5;
            return;
        }// end function

        public function copyFrom(param1:FlxCamera) : FlxCamera
        {
            if (param1.bounds == null)
            {
                this.bounds = null;
            }
            else
            {
                if (this.bounds == null)
                {
                    this.bounds = new FlxRect();
                }
                this.bounds.copyFrom(param1.bounds);
            }
            this.target = param1.target;
            if (this.target != null)
            {
                if (param1.deadzone == null)
                {
                    this.deadzone = null;
                }
                else
                {
                    if (this.deadzone == null)
                    {
                        this.deadzone = new FlxRect();
                    }
                    this.deadzone.copyFrom(param1.deadzone);
                }
            }
            return this;
        }// end function

        public function get zoom() : Number
        {
            return this._zoom;
        }// end function

        public function set zoom(param1:Number) : void
        {
            if (param1 == 0)
            {
                this._zoom = defaultZoom;
            }
            else
            {
                this._zoom = param1;
            }
            this.setScale(this._zoom, this._zoom);
            return;
        }// end function

        public function get alpha() : Number
        {
            return this._flashBitmap.alpha;
        }// end function

        public function set alpha(param1:Number) : void
        {
            this._flashBitmap.alpha = param1;
            return;
        }// end function

        public function get angle() : Number
        {
            return this._flashSprite.rotation;
        }// end function

        public function set angle(param1:Number) : void
        {
            this._flashSprite.rotation = param1;
            return;
        }// end function

        public function get color() : uint
        {
            return this._color;
        }// end function

        public function set color(param1:uint) : void
        {
            this._color = param1;
            var _loc_2:* = this._flashBitmap.transform.colorTransform;
            _loc_2.redMultiplier = (this._color >> 16) * 0.00392;
            _loc_2.greenMultiplier = (this._color >> 8 & 255) * 0.00392;
            _loc_2.blueMultiplier = (this._color & 255) * 0.00392;
            this._flashBitmap.transform.colorTransform = _loc_2;
            return;
        }// end function

        public function get antialiasing() : Boolean
        {
            return this._flashBitmap.smoothing;
        }// end function

        public function set antialiasing(param1:Boolean) : void
        {
            this._flashBitmap.smoothing = param1;
            return;
        }// end function

        public function getScale() : FlxPoint
        {
            return this._point.make(this._flashSprite.scaleX, this._flashSprite.scaleY);
        }// end function

        public function setScale(param1:Number, param2:Number) : void
        {
            this._flashSprite.scaleX = param1;
            this._flashSprite.scaleY = param2;
            return;
        }// end function

        public function getContainerSprite() : Sprite
        {
            return this._flashSprite;
        }// end function

        public function fill(param1:uint, param2:Boolean = true) : void
        {
            this._fill.fillRect(this._flashRect, param1);
            this.buffer.copyPixels(this._fill, this._flashRect, this._flashPoint, null, null, param2);
            return;
        }// end function

        function drawFX() : void
        {
            var _loc_1:Number = NaN;
            if (this._fxFlashAlpha > 0)
            {
                _loc_1 = this._fxFlashColor >> 24;
                this.fill((uint((_loc_1 <= 0 ? (255) : (_loc_1)) * this._fxFlashAlpha) << 24) + (this._fxFlashColor & 16777215));
            }
            if (this._fxFadeAlpha > 0)
            {
                _loc_1 = this._fxFadeColor >> 24;
                this.fill((uint((_loc_1 <= 0 ? (255) : (_loc_1)) * this._fxFadeAlpha) << 24) + (this._fxFadeColor & 16777215));
            }
            if (this._fxShakeOffset.x != 0 || this._fxShakeOffset.y != 0)
            {
                this._flashSprite.x = this.x + this._flashOffsetX + this._fxShakeOffset.x;
                this._flashSprite.y = this.y + this._flashOffsetY + this._fxShakeOffset.y;
            }
            return;
        }// end function

    }
}
